package com.chenxi.vhr.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chenxi.vhr.bean.*;
import com.chenxi.vhr.bean.common.Result;
import com.chenxi.vhr.bean.common.ResultPageInfo;
import com.chenxi.vhr.bean.message.MqMessage;
import com.chenxi.vhr.bean.vo.DepartmentTreeVo;
import com.chenxi.vhr.bean.vo.EmployeeVo;
import com.chenxi.vhr.mapper.*;
import com.chenxi.vhr.service.VhrEmployeeService;
import com.chenxi.vhr.utils.ExcelUtil;
import com.chenxi.vhr.utils.NasUtil;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 *
 */
@Service
public class VhrEmployeeServiceImpl extends ServiceImpl<VhrEmployeeMapper, VhrEmployee>
    implements VhrEmployeeService {

    @Autowired
    VhrEmployeeMapper employeeMapper;

    @Autowired
    VhrEmpSalaryMapper empSalaryMapper;

    @Autowired
    BaseDepartmentMapper departmentMapper;

    @Autowired
    BaseDictNationMapper dictNationMapper;

    @Autowired
    BaseDictPoliticsStatusMapper politicsStatusMapper;

    @Autowired
    VhrJobLevelMapper jobLevelMapper;

    @Autowired
    VhrPositionMapper positionMapper;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Override
    public ResultPageInfo listPage(Integer currentPage, Integer size, EmployeeVo employee) {
        if (currentPage != null) {
            currentPage = (currentPage - 1) * size;
        }
        if (employee.getDepartmentId() != null) {
            BaseDepartment baseDepartment = departmentMapper.selectById(employee.getDepartmentId());
            if (baseDepartment.getIsParent()) {
                List<Integer> idList = new ArrayList<>();
                getChildIdList(employee.getDepartmentId(), idList);
                // 去重2: Java8新特性
                // idList = idList.stream().distinct().collect(Collectors.toList());
                // 去重2: set去重
                // idList = new ArrayList<>(new TreeSet<Integer>(idList));
                // 去重3: 框架API
                idList = NasUtil.distinctList(idList);
                employee.setDeptIdList(idList);
                employee.setDepartmentId(null);
            }
        }
        List<EmployeeVo> list = employeeMapper.selectAllInfoByPage(currentPage, size, employee);
        Integer total = employeeMapper.count(employee);
        return ResultPageInfo.genPageInfo(list, total);
    }

    private void getChildIdList(Integer parentId, List<Integer> idList) {
        List<DepartmentTreeVo> childList = departmentMapper.getChildDeptByParentId(parentId);
        idList.add(parentId);
        childList.forEach(dept -> {
            if (dept.getIsParent()) {
                idList.add(dept.getId());
                getChildIdList(dept.getParentId(), idList);
            } else {
                idList.add(dept.getId());
            }
        });
    }

    @Override
    public Result genWorkNo() {
        Integer maxWorkNo = employeeMapper.getMaxWorkNo();
        return Result.ok("生成最新的工号", String.format("%08d", maxWorkNo + 1));
    }

    @Override
    public Result importExcel(MultipartFile file, List<String> fieldList) throws Exception {
        Result result = Result.ok("上传成功！");
        List<EmployeeVo> list = null;
        try {
            ExcelUtil excelUtil = new ExcelUtil(EmployeeVo.class);
            // 解析上传的文件到List
            list = excelUtil.parseExcelToList(file, fieldList);
            // 处理List中Vo中的Name的值重新设置为Id
            List<BaseDepartment> departmentList = departmentMapper.selectList(new QueryWrapper<BaseDepartment>());
            List<BaseDictNation> nationList = dictNationMapper.selectList(new QueryWrapper<BaseDictNation>());
            List<BaseDictPoliticsStatus> politicsStatusList = politicsStatusMapper.selectList(new QueryWrapper<BaseDictPoliticsStatus>());
            List<VhrJobLevel> jobLevelList = jobLevelMapper.selectList(new QueryWrapper<VhrJobLevel>());
            List<VhrPosition> positionList = positionMapper.selectList(new QueryWrapper<VhrPosition>());

            list.forEach(vo -> {
                // 部门
                departmentList.forEach(dept -> {
                    if (dept.getName().equals(vo.getDeptName())) {
                        vo.setDepartmentId(dept.getId());
                    }
                });
                // 民族
                nationList.forEach(nation -> {
                    if (nation.getName().equals(vo.getNationName())) {
                        vo.setNationId(nation.getId());
                    }
                });
                // 政治面貌
                politicsStatusList.forEach(politicsStatus -> {
                    if (politicsStatus.getName().equals(vo.getPoliticName())) {
                        vo.setPoliticId(politicsStatus.getId());
                    }
                });
                // 职称
                jobLevelList.forEach(jobLevel -> {
                    if (jobLevel.getName().equals(vo.getJobName())) {
                        vo.setJobLevelId(jobLevel.getId());
                    }
                });
                // 职位
                positionList.forEach(position -> {
                    if (position.getName().equals(vo.getPositionName())) {
                        vo.setPositionId(position.getId());
                    }
                });
            });
            System.out.println("解析完成......");
            // 数据插入数据库
            for (EmployeeVo item: list) {
                String workNo = item.getWorkNo();
                int count = employeeMapper.countByWorkNo(workNo);
                if (count != 0) {
                    result = Result.error("工号【" + workNo + "】重复，请检查数据！！");
                    return result;
                }
                item.setWorkNo(String.format("%08d", Integer.parseInt(item.getWorkNo())));
            }
            list.forEach(item -> {
                VhrEmployee entity = new VhrEmployee();
                NasUtil.copyProperties(item, entity);
                employeeMapper.insert(entity);
            });
        } catch (Exception e) {
            e.printStackTrace();
            result = Result.error(e.getMessage());
        }
        return result;
    }

    @Override
    public Result saveEmployee(VhrEmployee employee) {
        Result result = Result.ok("新增员工成功！");
        // 计算合同期限
        Double contractTerm = calculateContractTerm(employee.getBeginContract(), employee.getEndContract());
        employee.setContractTerm(contractTerm);
        int count = employeeMapper.insert(employee);
        // 发送消息到中间件，中间件接收后发送邮件
        EmployeeVo vo = employeeMapper.selectEmployeeVoById(employee.getId());
        MqMessage message = new MqMessage(vo, new Date());
        rabbitTemplate.convertAndSend("Mail-Queue", message);
        if (count == 0) {
            result = Result.error("员工新增失败！");
        }
        return result;
    }

    @Override
    public Result updateEmployee(VhrEmployee employee) {
        Result result = Result.ok("员工修改成功！");
        // 计算合同期限
        employee.setContractTerm(calculateContractTerm(employee.getBeginContract(), employee.getEndContract()));
        int count = employeeMapper.updateById(employee);
        if (count == 0) {
            result = Result.error("员工修改失败！");
        }
        return result;
    }

    @Override
    public ResultPageInfo listEmpWithSalary(Integer currentPage, Integer size) {
        if (currentPage != null) {
            currentPage = (currentPage - 1) * size;
        }
        List<EmployeeVo> list = employeeMapper.listEmpWithSalary(currentPage, size);
        Integer total = employeeMapper.count(null);
        return ResultPageInfo.genPageInfo(list, total);
    }

    @Override
    public Result updateEmpSalary(Integer empId, Integer salaryId) {
        // 可以使用SQL，注意：这种情况emp_id在表中必须是唯一的索引，即索引类型是 UNION
        // REPLACE INTO vhr_employee_sal(emp_id,salary_id) VALUES(xx,xx)
        QueryWrapper<VhrEmpSalary> wrapper = new QueryWrapper<>();
        wrapper.eq("emp_id", empId);
        Integer count = empSalaryMapper.selectCount(wrapper);
        if (count > 0) {
            empSalaryMapper.delete(wrapper);
        }
        VhrEmpSalary entity = new VhrEmpSalary();
        entity.setEmpId(empId);
        entity.setSalaryId(salaryId);
        int updCount = empSalaryMapper.insert(entity);
        return updCount > 0 ? Result.ok("修改成功！") : Result.error("修改失败！");
    }

    /**
     * 计算合同期限
     * @param beginContract
     * @param endContract
     * @return
     */
    private Double calculateContractTerm(Date beginContract, Date endContract) {
        SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
        SimpleDateFormat monthFormat = new SimpleDateFormat("MM");
        DecimalFormat decimalFormat = new DecimalFormat("##.00");

        Double month = (Double.parseDouble(yearFormat.format(endContract)) - Double.parseDouble(yearFormat.format(beginContract))) * 12
                + Double.parseDouble(monthFormat.format(endContract))  -  Double.parseDouble(monthFormat.format(beginContract));
        return Double.parseDouble(decimalFormat.format(month / 12));
    }

}




